package com.app.web.socketio
import com.corundumstudio.socketio.SocketIOClient
import com.corundumstudio.socketio.SocketIOServer
import com.corundumstudio.socketio.annotation.OnConnect
import com.corundumstudio.socketio.annotation.OnDisconnect
import com.frame.filter.SessionStore
import groovy.transform.CompileStatic
import groovy.transform.TypeChecked
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Component

import javax.annotation.PostConstruct
import javax.annotation.PreDestroy
/**
 * 个人实时消息通知
 * Created by three on 14-9-29.
 */
@CompileStatic
@TypeChecked
@Component
public class PersonalMessageNotify {

    @Autowired
    private SocketIOServer server;

    private static Map<String, UUID> userMap = new HashMap<String, UUID>();
    private static List<PersonalMessage> messageList = new ArrayList<PersonalMessage>();
    private Thread sendThread = null;
    private boolean stop = false;

    /**
     * 用户链接，加入系统推送列表
     * @param client
     */
    @OnConnect
    public void onConnectHandler(SocketIOClient client) {
        userMap.put((String) SessionStore.currentSession().getId(), client.getSessionId());
    }

    @OnDisconnect
    public void onDisconnectHandler(SocketIOClient client) {
        userMap.remove(client.getSessionId());
    }

    @PostConstruct
    public void start() {
        // 发送线程
        sendThread = new Thread(new Runnable() {
            @Override
            public void run() {
                while (!stop) {
                    try {
                        synchronized (messageList) {
                            if(messageList.size()>0) {
                                List<PersonalMessage> msgList = new ArrayList<PersonalMessage>();
                                for(PersonalMessage msg: messageList) {
                                    try {
                                        SocketIOClient client = server.getClient(userMap.get(msg.getUserToken()));
                                        client.sendEvent(msg.getName(), msg.getData());
                                    } catch (Exception e) { // 客户端发送异常，保留信息
                                        msg.errorIncr();
                                        if(msg.getErrorTimes()<10){
                                            msgList.add(msg);
                                        }
                                    }
                                }
                                messageList.clear();
                                messageList.addAll(msgList);
                            }
                            messageList.wait(10000);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        sendThread.start();

        // TODO 消息测试发送，正式环境需要去掉
        new Thread(new Runnable() {
            @Override
            void run() {
                int id = 0;
                while (true) {
                    Thread.sleep((int)(Math.random()*10000));
                    String[] userKey = userMap.keySet().toArray();
                    int index = (int) (Math.random()*(userKey.length+1));
                    String user = "";
                    try {
                        user = userKey[index];
                    } catch (Exception e) {
//                        e.printStackTrace();
                    }
                    Map<String, Object> data = new HashMap<>();
                    data.put("content", UUID.randomUUID().toString());
                    data.put("id", id++);
                    send(new PersonalMessage(user, "personal_MSG", data));
                }
            }
        }).start();
    }

    @PreDestroy
    public void stop() {
        stop = true;
        if(null!=sendThread) {
            sendThread.interrupt();
        }
    }

    public static void send(PersonalMessage msg) {
        synchronized (messageList) {
            messageList.add(0, msg);
            messageList.notifyAll();
        }
    }
}
